package com.itheima.health.exception;

import com.itheima.health.common.MessageConst;
import com.itheima.health.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.ServletException;
import org.springframework.security.access.AccessDeniedException;

/**
 * 统一的异常处理
 * 核心逻辑：
 * 1-首先匹配类
 * 2-匹配父类
 * 3-如果匹配到多个父类，则选择继承关系最近的父类
 */
@RestControllerAdvice(basePackages = {"com.itheima.health.controller"})
@Slf4j
public class MyExceptionHandler {
    /**
     * 服务端异常，直接提示操作失败
     */
    @ResponseStatus(HttpStatus.OK) // 返回的http状态为 200
    @ExceptionHandler({Exception.class})
    public Result exception(Exception e) {
        log.error("", e);
        //直接提示操作失败
        return new Result(false, MessageConst.ACTION_FAIL);
    }
    /**
     * 希望交给spring处理的异常，所以继续上抛
     */
    @ExceptionHandler({
            ServletException.class,                     // mediaType不匹配、method不匹配……
            HttpMessageConversionException.class,       //http body转换异常，@RequestBody的参数
            MethodArgumentNotValidException.class ,     //http请求缺少查询参数
            MethodArgumentTypeMismatchException.class   //http请求参数类型不匹配
    })
    public Result servletException(Exception e) throws Exception {
        //继续上抛，由spring处理
        throw e;
    }

    /**
     * @Author: 15041
     * @Date: 16:00 2021/1/4
     * @Parms: [e]
     * @ReturnType: com.itheima.health.entity.Result
     *Description: 自定义异常调用
    */
    @ResponseStatus(HttpStatus.OK) //返回的http状态为200
    @ExceptionHandler({BusinessException.class}) //连接自定义异常
    public Result businessEx(Exception e){
        log.error("",e);
        //直接提示操作失败，把出现的异常返回
        return new Result(false,e.getMessage());
    }

    @ResponseStatus(HttpStatus.OK) //返回的http状态为200
    @ExceptionHandler({AccessDeniedException.class}) //连接自定义异常
    public Result accessDeniedException(Exception e){
        log.error("",e);
        //直接提示操作失败，把出现的异常返回
        return new Result(false,"权限不足，请先联系管理员");
    }

}
